﻿#define _CRT_SECURE_NO_WARNINGS 1

#include <iostream>
using namespace std;

// nullptr可以调用类成员函数
void test1()
{
	class animal {
	public:
		virtual void sleep() { cout << "animal sleep" << endl; }
		void breathe() { cout << "animal breathe haha" << endl; }
	};
	class fish :public animal {
	public:
		void breathe() { cout << "fish bubble" << endl; }
	};
	
	animal* pAn = nullptr;
	pAn->breathe(); // 输出：animal breathe haha
	fish* pFish = nullptr;
	pFish->breathe(); // 输出：fish bubble


	//animal an;
	//animal* pAn = &an;
	//pAn->breathe();

	//fish f;
	//fish* pFish = &f;
	//pFish->breathe();
}

void myswap(int* a, int* b)
{
	int tmp = *a;
	*a = *b;
	*b = tmp;
}

void test2()
{
	int a = 10;
	int b = 20;
	int* pa = &a;
	int* pb = &b;
	cout << a << " " << b << endl;
	myswap(pa, pb);
	cout << a << " " << b << endl;
}

void test3()
{
	class A
	{
	public:
		virtual void fun()
		{
			cout << "A";
		}
	};
	class B :public A
	{
	public:
		virtual void fun()
		{
			cout << "B";
		}
	};

	A* a = new B();
	a->fun(); // 输出B，A类中的fun在B类中重写

	B b;
	A& aa = b; // 父类对子类的引用也是重写
	a->fun();
}

void func_int(void* a)
{
	printf("%d\n", *(int*)a); //输出int类型，注意 void * 转化为int
}

void func_double(void* b)
{
	printf("%.2f\n", *(double*)b);
}

typedef void (*ptr)(void*); //typedef申明一个函数指针

void c_func(ptr p, void* param)
{
	p(param); //调用对应函数
}

void test4()
{
	int a = 23;
	double b = 23.23;
	c_func(func_int, &a);
	c_func(func_double, &b);
}

// #1 模板定义
template<class T>
struct TemplateStruct
{
	TemplateStruct()
	{
		cout << sizeof(T) << endl;
	}
};

// #2 模板显示实例化
template struct TemplateStruct<int>;

// #3 模板具体化
template<> struct TemplateStruct<double>
{
	TemplateStruct() {
		cout << "--8--" << endl;
	}
};

void test5()
{
	TemplateStruct<int> intStruct;
	TemplateStruct<double> doubleStruct;

	// #4 模板隐式实例化
	TemplateStruct<char> llStruct;
}

class first 
{
public:
	first() :num(new int(0)) 
	{
		cout << "construct!" << endl;
	}
	
	//移动构造函数
	first(first&& d) :num(d.num) 
	{
		d.num = NULL;
		cout << "first move construct!" << endl;
	}

public: //这里应该是 private，使用 public 是为了更方便说明问题
	int* num;
};

class second 
{
public:
	second() :fir() {}

	//用 first 类的移动构造函数初始化 fir
	second(second&& sec) :fir(move(sec.fir)) 
	{
		cout << "second move construct" << endl;
	}

public: //这里也应该是 private，使用 public 是为了更方便说明问题
	first fir;
};

void test6()
{
	second oth;
	//cout << *oth.fir.num << endl; //程序报运行时错误
	second oth2 = move(oth);
	//cout << *oth.fir.num << endl; //程序报运行时错误
}

class Person {
public:
	//虚函数
	virtual void GetName() {
		cout << "PersonName:xiaosi" << endl;
	};
};

class Student :public Person {
public:
	void GetName() {
		cout << "StudentName:xiaosi" << endl;
	};
};

void test7()
{
	//指针
	Person* person = new Student();
	//基类调用子类的函数
	person->GetName();//StudentName:xiaosi
}


void Swap(int* a, int* b)
{
	int tmp = *a;
	*a = *b;
	*b = tmp;
}

// 向下调整算法，建小堆，排降序
void AdjustDown(int* arr, int n, int parent)
{
	int child = parent * 2 + 1;
	while (child < n)
	{
		if (child + 1 < n && arr[child + 1] < arr[child])
		{
			++child;
		}

		if (arr[child] < arr[parent])
		{
			Swap(&arr[child], &arr[parent]);
			parent = child;
			child = parent * 2 + 1;
		}
		else
		{
			break;
		}
	}
}

// 向上调整算法，建大堆，排升序
void AdjustUp(int* arr, int n, int child)
{
	int parent = (child - 1) / 2;

	while (child >= 0)
	{
		if (arr[child] > arr[parent])
		{
			Swap(&arr[child], &arr[parent]);
			child = parent;
			parent = (child - 1) / 2;
		}
		else
		{
			break;
		}
	}
}

// 堆排序只要生成一个向下调整算法即可
void heapSort(int* arr, int n)
{
	//// 降序
	//for (int i = 1; i < n; i++)
	//{
	//	AdjustUp(arr, n, i);
	//}
	//int end = n - 1;
	//while (end > 0)
	//{
	//	Swap(&arr[end], &arr[0]);
	//	AdjustDown(arr, end, 0); // 大根堆降序时和小堆相反
	//	--end;
	//}

	////升序
	for (int i = (n - 1 - 1) / 2; i >= 0; --i)
	{
		AdjustDown(arr, n, i);
	}
	int end = n - 1;
	while (end > 0)
	{
		Swap(&arr[end], &arr[0]);
		AdjustDown(arr, end, 0);
		--end;
	}
}

void test8() // 堆排序
{
	int arr[] = { 2,5,8,1,9,4,3,6,7,0 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	heapSort(arr, sz);
	for (int i = 0; i < sz; i++)
	{
		cout << arr[i] << " ";
	}
}

#include <thread>
#include <mutex>

std::mutex mtx;
std::condition_variable odd_cv;
std::condition_variable even_cv;

int counts = 1;

void printOdd() 
{
	while (counts <= 100) 
	{
		std::unique_lock<std::mutex> lock(mtx);
		if (counts >= 100) break;
		odd_cv.wait(lock, []() { return counts % 2 == 1; });
		std::cout << "thread: " << std::this_thread::get_id() << " : " << counts++ << std::endl;
		even_cv.notify_one();
	}
} 

void printEven() 
{
	while (counts <= 100) 
	{
		std::unique_lock<std::mutex> lock(mtx);
		if (counts >= 100) break;
		even_cv.wait(lock, []() {return counts % 2 == 0; });
		std::cout << "thread: " << std::this_thread::get_id() << " : " << counts++ << std::endl;
		odd_cv.notify_one();
	}
}

// 俩线程相互打印奇数和偶数（1-100）
void test9() 
{
	std::thread t1(printOdd);
	std::thread t2(printEven);

	t1.join();
	t2.join();
}

void quickSort(int* arr, int left, int right)
{
	if (left >= right) return;

	int keyi = left;
	int begin = left, end = right;
	while (left < right)
	{
		while (left < right && arr[right] >= arr[keyi])
		{
			right--;
		}

		while (left < right && arr[left] <= arr[keyi])
		{
			left++;
		}

		Swap(&arr[left], &arr[right]);
	}
	Swap(&arr[keyi], &arr[left]);
	keyi = left;

	quickSort(arr, begin, keyi - 1);
	quickSort(arr, keyi + 1, end);
}

// 快速排序
void test10()
{
	int arr[] = { 9,2,5,7,1,5,0,4,3,6,8 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	quickSort(arr, 0, sz - 1);
	for (auto& e : arr) cout << e << " ";
}

int _strlen(const char* str)
{
	int count = 0;
	while (*str)
	{
		str++;
		count++;
	}
	return count;
}

char* _strcpy(char* dest ,const char* src)
{
	char* ret = dest;
	while (*src)
	{
		*dest = *src;
		dest++;
		src++;
	}
	return ret;
}

void* _memcpy(void* dest, const void* src,int count)
{
	void* ret = dest;
	while (count--)
	{
		*(char*)dest = *(char*)src;
		dest = (char*)dest + 1;
		src = (char*)src + 1;
	}
	return ret;
}

void* _memmove(void* dst, const void* src, size_t count)
{
	void* ret = dst;
	if (dst <= src || (char*)dst >= ((char*)src + count)) 
	{
		while (count--) 
		{
			*(char*)dst = *(char*)src;
			dst = (char*)dst + 1;
			src = (char*)src + 1;
		}
	}
	else 
	{
		dst = (char*)dst + count - 1;
		src = (char*)src + count - 1;

		while (count--) 
		{
			*(char*)dst = *(char*)src;
			dst = (char*)dst - 1;
			src = (char*)src - 1;
		}
	}
	return(ret);
}

// 字符串函数
void test11()
{
	char s1[] = "abcdefj";
	char s2[] = "12345";
	cout << _strlen(s1) << endl;
	cout << s1 << " " << s2 << endl;
	char* s3 = _strcpy(s1 + 1, s2);
	cout << s3 << endl;
	cout << s1 << " " << s2 << endl;

	_memcpy(s1 + 2, s2, 1);
	cout << s1 << endl;

	char s4[] = "12345678";
	_memmove(s4+2, s4, 5);
	cout << s4 << endl;
}


class ptr_test
{
public:
	ptr_test()
	{
		cout << "ptr_test 构造函数" << endl;
	}

	~ptr_test()
	{
		cout << "ptr_test 析构函数" << endl;
	}

private:
	int a;
	char b;
};

/*
template<class T>
class my_shared_ptr
{
public:
	my_shared_ptr()
		:_ptr(nullptr)
		, _pcount(new int(0))
	{
		cout << "默认构造函数" << endl;
	}

	my_shared_ptr(T* ptr)
		:_ptr(ptr)
		, _pcount(new int(1))
	{
		cout << "构造函数" << endl;
	}

	~my_shared_ptr()
	{
		cout << "析构函数" << endl;
		*_pcount--;
		if (*_pcount == 0)
		{
			delete _ptr;
			delete _pcount;
		}
	}

	T* operator*()
	{
		return *_ptr;
	}

	T& operator->()
	{
		return _ptr;
	}
	
	my_shared_ptr(const my_shared_ptr<T>& msp)
		:_ptr(msp._ptr)
		, _pcount(msp._pcount)
	{
		cout << "拷贝构造" << endl;
		(*_pcount)++;
	}
	
	my_shared_ptr<T>& operator=(const my_shared_ptr<T>& msp)
	{
		if (_ptr == msp._ptr)
		{
			return *this;
		}

		(*_pcount)--;
		if (*_pcount == 0)
		{
			delete _ptr;
			delete _pcount;
			cout << "赋值运算符重载" << endl;
		}

		// 资源改变
		_ptr = msp._ptr;
		_pcount = msp._pcount;
		(*_pcount)++;

		return *this;
	}

	int use_count() const
	{
		return *_pcount;
	}

	T* get() const
	{
		return _ptr;
	}

private:
	T* _ptr;
	int* _pcount;
};
*/

template<class T>
class my_shared_ptr
{
public:
	my_shared_ptr()
		:_ptr(nullptr)
		, _pcount(new int(0))
	{
		cout << "my_shared_ptr()" << endl;
	}

	my_shared_ptr(T* msp)
		:_ptr(msp)
		, _pcount(new int(1))
	{
		cout << "my_shared_ptr(T*)" << endl;
	}

	~my_shared_ptr()
	{
		if (--(*_pcount) == 0)
		{
			delete _ptr;
			delete _pcount;
			cout << "~my_shared_ptr()" << endl;
		}
	}

	my_shared_ptr(const my_shared_ptr<T>& msp)
		:_ptr(msp._ptr)
		, _pcount(msp._pcount)
	{
		cout << "my_shared_ptr(const my_shared_ptr<T> msp)" << endl;
		++(*_pcount);
	}

	my_shared_ptr& operator=(const my_shared_ptr<T>& msp)
	{
		if (this->_ptr == msp._ptr)
		{
			return *this;
		}

		--(*(this->_pcount));
		if ((*_pcount) == 0)
		{
			delete _ptr;
			delete _pcount;
			cout << "my_shared_ptr& operator=(const my_shared_ptr<T>& msp)" << endl;
		}

		_ptr = msp._ptr;
		_pcount = msp._pcount;

		return *this;
	}

	T* operator*()
	{
		return *_ptr;
	}

	T& operator->()
	{
		return _ptr;
	}

	int use_count() const
	{
		return *_pcount;
	}

	T* get() const
	{
		return _ptr;
	}

private:
	T* _ptr;
	int* _pcount;
};

void test12()
{
	//shared_ptr<ptr_test> p(new ptr_test());
	//shared_ptr<ptr_test> p1(p);
	//shared_ptr<ptr_test> p2 = p1;

	my_shared_ptr<ptr_test> mp1(new ptr_test());
	my_shared_ptr<ptr_test> mp2(mp1);
	my_shared_ptr<ptr_test> mp3 = mp2;

	my_shared_ptr<ptr_test> mp4(new ptr_test());
	cout << "use_count：" << mp1.use_count() << endl;
	mp3 = mp4 = mp1;
}

#include <string>

//实现一个简单的命令行计算器，能够进行加、减、乘、除运算，并处理错误输入
void calculator()
{
	cout << "请输入所要计算的算式：" << endl;
	string s;
	cin >> s;
	int req = 0;
	// 只能10以内
	//switch (s[1])
	//{
	//case '+':
	//	req = s[0] - '0' + s[2] - '0';
	//	break;
	//case '-':
	//	req = s[0] - '0' - s[2] - '0';
	//	break;
	//case '*':
	//	req = s[0] - '0' * s[2] - '0';
	//	break;
	//case '/':
	//	if (s[2] - '0' != 0)
	//		req = s[0] - '0' / s[2] - '0';
	//	break;
	//default:
	//	cout << "除0错误" << endl;
	//	break;
	//}
	// 进行字符串的分割
	int n1 = 0, n2 = 0;
	char ch;
	int n = s.size();
	int pos=0; // 符号位的位置
	for (int i = 0; i < n; ++i)
	{
		if (s[i] == '+' || s[i] == '-' || s[i] == '*' || s[i] == '/')
		{
			pos = i;
			ch = s[i];
			break;
		}
	}
	string s1 = s.substr(0, pos);
	string s2 = s.substr(pos + 1, n);
	n1 = stoi(s1);
	n2 = stoi(s2);
	//cout << n1 << " " << n2 << endl;
	switch (ch)
	{
	case '+':
		req = n1 + n2;
		break;
	case '-':
		req = n1 - n2;
		break;
	case '*':
		req = n1 * n2;
		break;
	case '/':
		if(n2!=0) req = n1 / n2;
		else
			cout << "除数不能为 0" << endl;
		return;
		break;
	default:
		cout << "输入格式错误" << endl;
		break;
	}
	cout << "输入完成，计算的结果为：" << req << endl;
}

#include <regex>

// 使用正则表达式
void calculator1()
{
	string exp;
	cout << "输入算式:" << endl;
	cin >> exp;
	//exp = "12+34";
	regex pattenN1("\\d+");
	regex pattenN2("\\d+$"); // 匹配数字
	regex pattenOp("[+\\-*/]"); // 匹配符号
	smatch n1;
	smatch n2;
	smatch op;
	int req;
	if (std::regex_search(exp, n1, pattenN1))
	{
		cout << n1[0].str()<<endl;
		if (std::regex_search(exp, n2, pattenN2))
		{
			cout << n2[0].str() << endl;
			if (std::regex_search(exp, op, pattenOp))
			{
				char mop = op[0].str()[0];
				cout << op[0].str() << endl;
				int n = stoi(n1[0].str());
				int m = stoi(n2[0].str());
				switch (mop) {
				case '+':
					req = n + m;
					break;
				case '-':
					req = n - m;
					break;
				case '*':
					req = n * m;
					break;
				case '/':
					if (m != 0) {
						req = n / m;
					}
					else {
						std::cout << "除数不能为零。" << std::endl;
						return;
					}
					break;
				}
				cout << "计算结果为：" << req << endl;
			}
		}
	}
}

void test13()
{
	char ch;
	do
	{
		//calculator();
		calculator1();
		cout << "输入任意键启动计算器，退出请按e/E" << endl;
		cin >> ch;
	} while (ch != 'e' && ch != 'E');
}

// 高精度相乘
string solve(string s, string t)
{
	reverse(s.begin(), s.end());
	reverse(t.begin(), t.end());
	int m = s.size(), n = t.size();
	vector<int> tmp(m + n);
	// 1. ⽆进位相乘相加
	for (int i = 0; i < m; i++)
	{
		for (int j = 0; j < n; j++)
		{
			tmp[i + j] += (s[i] - '0') * (t[j] - '0');
		}
	}
	// 2. 处理进位
	int c = 0;
	string ret;
	for (auto x : tmp)
	{
		c += x;
		ret += c % 10 + '0';
		c /= 10;
	}
	while (c)
	{
		ret += c % 10 + '0';
		c /= 10;
	}
	// 3. 处理前导零
	while (ret.size() > 1 && ret.back() == '0') ret.pop_back();

	reverse(ret.begin(), ret.end());
	return ret;
}

void test14()
{
	string s1, s2;
	cin >> s1 >> s2;
	cout << solve(s1, s2) << endl;
}

int main()
{
	//test1();
	//test2();
	//test3();
	//test4();
	//test5();
	//test6();
	//test7();
	//test8();
	//test9();
	//test10();
	//test11();
	//test12();
	//test13();
	test14();
	return 0;
 }